package com.pets.springboot_petshop.controller;

import com.pets.springboot_petshop.entity.User;
import com.pets.springboot_petshop.entity.UserDTO;
import com.pets.springboot_petshop.pojo.Result;
import com.pets.springboot_petshop.service.EmailService;
import com.pets.springboot_petshop.service.UserService;
import com.pets.springboot_petshop.util.JwtUtil;
import com.pets.springboot_petshop.util.Md5Util;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private CacheManager cacheManager;


    @PostMapping("/login")
    public Result<String> login(
            @NotBlank(message = "邮箱不能为空")
            @Pattern(regexp = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$", message = "邮箱格式不正确")
            @RequestParam("email") String email,
            @NotBlank(message = "密码不能为空")
            @Pattern(regexp = "^.{5,16}$", message = "密码长度必须在5到16个字符之间")
            @RequestParam("password") String password) {
        //根据邮箱查询
        User user = userService.findByUseremail(email);
        //判断用户是否存在
        if (user == null) {
            return Result.error("邮箱错误");
        }
        //判断密码是否正确
        //先进行加密再进行对比
        if (Md5Util.getMD5String(password).equals(user.getPassword())) {
            //登录成功
            Map<String, Object> map = new HashMap<>();
            map.put("id", user.getId());
            map.put("username", user.getUsername());
            String token = JwtUtil.genToken(map);
            return Result.success(token);
        }
        return Result.error("密码错误");
    }

    @GetMapping("/findByUserName")
    public Result<UserDTO> findByUserName(@RequestParam String username) {
        User user = userService.findByUserName(username);
        if (user == null) {
            return Result.error("不存在用户");
        } else {
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        }
    }
    @GetMapping("/userInfo")
    public Result<UserDTO> adminInfo(@RequestHeader(name = "Authorization") String token) {
        // 根据令牌查询相应的用户信息
        Map<String,Object> map = JwtUtil.parseToken(token);
        int id = (int) map.get("id");
        System.out.println(" id = " + id);
        // 检查用户是否存在
        User user = userService.select(id);
        if (user == null) {
            return Result.error("用户不存在");
        }else {
            user.setId(id);
            // 将Admin对象转换为AdminDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        }
    }

    @GetMapping("/findByUseremail")
    public Result<UserDTO> findByUseremail(@RequestParam String email) {
        User user = userService.findByUseremail(email);
        if (user == null) {
            return Result.error("不存在用户");
        } else {
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        }
    }
    //根据用户名模糊查询用户
    @GetMapping("/selectName")
    public Result<List<UserDTO>> selectName(@RequestParam String username) {
        List<User> users = userService.selectName(username);
        if (users == null || users.isEmpty()) {
            return Result.error("不存在用户");
        } else {
            // 使用 Stream 将 List<User> 转换为 List<UserDTO>
            List<UserDTO> userDTOs = users.stream()
                    .map(user -> userService.convertToUserDTO(user))
                    .collect(Collectors.toList());
            return Result.success(userDTOs);
        }
    }
    //根据用户邮箱模糊查询用户
    @GetMapping("/selectemail")
    public Result<List<UserDTO>> selectemail(@RequestParam String email) {
        List<User> users = userService.selectemail(email);
        if (users == null || users.isEmpty()) {
            return Result.error("不存在用户");
        } else {
            // 使用 Stream 将 List<User> 转换为 List<UserDTO>
            List<UserDTO> userDTOs = users.stream()
                    .map(user -> userService.convertToUserDTO(user))
                    .collect(Collectors.toList());
            return Result.success(userDTOs);
        }
    }

    // 发送验证码
    @GetMapping("/sendCode")
    public Result<String> sendCode(@RequestParam String email) {
        if (email == null || email.trim().isEmpty()) {
            return Result.error("邮箱不能为空");
        }

        String randomCode = emailService.sendemail(email);
        cacheCode(email, randomCode);

        return Result.success("验证码已发送至您的邮箱");
    }

    // 检查验证码
    @GetMapping("/checkCode")
    public Result<String> checkCode(@RequestParam String code, @RequestParam String email) {
        System.out.println("检查验证码请求：邮箱 = " + email + ", 输入的验证码 = " + code);
        String cachedCode = getCodeFromCache(email);
        if (cachedCode == null || !cachedCode.equals(code)) {
            return Result.error("验证码错误或已过期");
        }
        removeFromCache(email);
        System.out.println("验证码正确");

        return Result.success("验证码正确");
    }

    // 修改密码
    @PostMapping("/updatePassword")
    public Result<String> updatePassword(@RequestBody User user) {
        String email = user.getEmail();
        String code = user.getCode(); // 验证码

        // 验证邮箱验证码
        Result<String> checkCodeResult = checkCode(code, email);
        if (!checkCodeResult.isSuccess()) {
            return Result.error("验证码错误");
        }
        removeFromCache(user.getEmail());
        boolean updateSuccess = userService.updateUserpassword(user);
        if (updateSuccess) {
            return Result.success("密码修改成功");
        } else {
            return Result.error("密码修改失败");
        }
    }

    @PostMapping("/register")
    public Result registerUser(@RequestBody Map<String, String> payload) {
        String username = payload.get("username");
        String password = payload.get("password");
        String email = payload.get("email");
        String code = payload.get("code"); // 验证码

        // 验证邮箱验证码
        Result<String> checkCodeResult = checkCode(code, email);
        if (!checkCodeResult.isSuccess()) {
            return Result.error("验证码错误");
        }

        User existingUserByEmail = userService.findByUseremail(email);
        User existingUserByUsername = userService.findByUserName(username);
        if (existingUserByEmail != null) {
            return Result.error("邮箱已使用");
        }
        if (existingUserByUsername != null) {
            return Result.error("用户名已被占用");
        }

        // 注册新用户
        userService.addUser(username, password, email);
        return Result.success("注册成功");
    }

    /**
     * 使用Spring的缓存管理器从名为"verificationCodes"的缓存中获取验证码。
     *
     * @param email 用户的邮箱地址，用作缓存中验证码的键。
     * @return 缓存中的验证码，如果不存在则返回null。
     */
    @Cacheable(value = "verificationCodes", key = "#email")
    public String getCodeFromCache(String email) {
        // 从缓存中获取指定邮箱的验证码
        return cacheManager.getCache("verificationCodes").get(email, String.class);
    }

    /**
     * 将验证码存储到名为"verificationCodes"的缓存中。
     *
     * @param email 用户的邮箱地址，用作缓存中验证码的键。
     * @param code 要缓存的验证码。
     */
    public void cacheCode(String email, String code) {
        // 将验证码与邮箱地址关联并存储到缓存中
        cacheManager.getCache("verificationCodes").put(email, code);
    }

    /**
     * 从名为"verificationCodes"的缓存中移除指定邮箱的验证码。
     *
     * @param email 用户的邮箱地址，用作缓存中验证码的键。
     */
    @CacheEvict(value = "verificationCodes", key = "#email")
    public void removeFromCache(String email) {
        // 从缓存中移除指定邮箱的验证码
    }

    @PostMapping("/deleteUserById")
    public Result deleteUserById(@RequestParam int id){
        if (userService.deleteUserById(id)>0){
            return Result.success("删除成功");
        }else {
            return Result.error("删除失败");
        }
    }


    @PostMapping("/updateUserById")
    public Result<UserDTO> updateUserById(@RequestBody User user){
        if (userService.updateUserById(user) > 0) {
            // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        } else {
            return Result.error("修改数据失败");
        }
    }

    @PostMapping("/updateUser")
    public Result<UserDTO> updateUser(@RequestBody User user){
        if (userService.updateUser(user) > 0) {
            // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        } else {
            return Result.error("修改数据失败");
        }
    }
    @PostMapping("/updateimg")
    public Result<UserDTO> updateimg(@RequestBody User user ,@RequestHeader(name = "Authorization") String token) {
        // 根据令牌查询相应的用户信息
        Map<String,Object> map = JwtUtil.parseToken(token);
        int id = (int) map.get("id");
        System.out.println(" id = " + id);
        // 检查用户是否存在
        User user1 = userService.select(id);
        if (user1 == null) {
            return Result.error("用户不存在");
        }
        user.setId(id);
        if (userService.updateimg(user) > 0) {
            // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        } else {
            return Result.error("修改数据失败");
        }
    }
    //修改用户名
    @PostMapping("/updateusername")
    public Result<UserDTO> updateusername(@RequestBody User user, @RequestHeader(name = "Authorization") String token) {
            // 根据令牌查询相应的用户信息
            Map<String,Object> map = JwtUtil.parseToken(token);
            int id = (int) map.get("id");
            System.out.println(" id = " + id);
            // 检查用户是否存在
            User user1 = userService.select(id);
            if (user1 == null) {
                return Result.error("用户不存在");
            }
           user.setId(id);
            // 获取新用户名
            String newUsername = user.getNewusername();
            if (newUsername == null || newUsername.trim().isEmpty()) {
                return Result.error("新用户名不能为空");
            }

            // 检查新用户名是否已被占用
            User existingUserByUsername = userService.findByUserName(newUsername);
            if (existingUserByUsername != null) {
                return Result.error("用户名已被占用");
            }

            // 更新用户信息
            user.setEmail(user1.getEmail());
            user.setUsername(newUsername);
            if (userService.updateusername(user) > 0) {
                // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
                UserDTO userDTO = userService.convertToUserDTO(user);
                return Result.success(userDTO);
            } else {
                return Result.error("修改数据失败");
            }
    }
    //修改用户手机号
    @PostMapping("/updatephone")
    public Result<UserDTO> updatephone(@RequestBody User user ,@RequestHeader(name = "Authorization") String token) {
        // 根据令牌查询相应的用户信息
        Map<String,Object> map = JwtUtil.parseToken(token);
        int id = (int) map.get("id");
        System.out.println(" id = " + id);
        // 检查用户是否存在
        User user1 = userService.select(id);
        if (user1 == null) {
            return Result.error("用户不存在");
        }
        user.setId(id);
        // 验证邮箱验证码
        String email = user.getEmail();
        String code = user.getCode();
        Result<String> checkCodeResult = checkCode(code, email);
        if (!checkCodeResult.isSuccess()) {
            return Result.error("验证码错误");
        }
        if (userService.updatephone(user) > 0) {
            // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        } else {
            return Result.error("修改数据失败");
        }
    }
    //修改用户邮箱
    @PostMapping("/updatemail")
    public Result<UserDTO> updatemail(@RequestBody User user ,@RequestHeader(name = "Authorization") String token) {
        // 根据令牌查询相应的用户信息
        Map<String,Object> map = JwtUtil.parseToken(token);
        int id = (int) map.get("id");
        System.out.println(" id = " + id);
        // 检查用户是否存在
        User user1 = userService.select(id);
        if (user1 == null) {
            return Result.error("用户不存在");
        }
        user.setId(id);
        // 验证邮箱验证码
        String email = user.getEmail();
        String code = user.getCode();
        String newEmail = user.getNewemail();
        Result<String> checkCodeResult = checkCode(code, email);
        if (!checkCodeResult.isSuccess()) {
            return Result.error("验证码错误");
        }
        User existingUserByEmail = userService.findByUseremail(newEmail);
        if (existingUserByEmail != null) {
            return Result.error("新邮箱已使用");
        }
        user.setEmail(newEmail);
        if (userService.updatemail(user) > 0) {
            // 更新成功后，使用服务层的方法将User对象转换为UserDTO对象
            UserDTO userDTO = userService.convertToUserDTO(user);
            return Result.success(userDTO);
        } else {
            return Result.error("修改数据失败");
        }
    }

    @GetMapping("/UserfindAll")
    public Result<List<UserDTO>> UserfindAll(){
        // 获取所有User对象的列表
        List<User> users = userService.UserfindAll();
        if (users == null || users.isEmpty()) {
            return Result.error("获取数据失败");
        } else {
            // 使用服务层的方法将User对象列表转换为UserDTO对象列表
            List<UserDTO> userDTOs = users.stream()
                    .map(user -> userService.convertToUserDTO(user))
                    .collect(Collectors.toList());
            return Result.success(userDTOs);
        }
    }
    @PostMapping("/admindelete")
    public Result admindelete(@RequestBody Map<String, Object> payload) {
        try {
            // 从payload中获取orderIds
            List<Integer> orderIdList = (List<Integer>) payload.get("ids");
            if (orderIdList == null || orderIdList.isEmpty()) {
                return Result.error("未提供有效的ID列表");
            }

            // 将List转换为int数组
            int[] ids = new int[orderIdList.size()];
            for (int i = 0; i < orderIdList.size(); i++) {
                ids[i] = orderIdList.get(i);
            }

            int affectedRows = userService.admindelete(ids);
            if (affectedRows > 0) {
                return Result.success("删除成功");
            } else {
                return Result.error("删除失败");
            }
        } catch (ClassCastException e) {
            return Result.error("ID列表格式错误，应为整数数组");
        } catch (Exception e) {
            return Result.error("服务器错误：" + e.getMessage());
        }
    }

}